package adke.models;

import adke.Util;
import adke.gui.Overview;
import adke.gui.animations.ParticleAnimation;
import adke.listeners.GameListener;
import adke.listeners.PlayerListener;
import adke.managers.AnimationManager;
import adke.managers.ColorManager;
import adke.managers.GameManager;
import adke.managers.GamePowerupManager;
import adke.managers.InputManager;
import adke.managers.NameManager;
import adke.managers.PlayerManager;
import adke.managers.PlayerPowerupManager;
import adke.managers.ScoreManager;
import adke.models.powerups.AbilityPowerup;
import adke.models.powerups.Powerup;
import java.awt.Color;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.util.Vector;

// klasse die alle variabelen van een spelende speler bijhoud.
// bijvoorbeeld, de positie, kleur, score,

// alles wat niet private is hebben we nodig in AI

public class Player implements GameListener
{
    // er kunnen listeners worden toegevoegd om bepaalde eigenschappen van een player te monitoren
    private Vector<PlayerListener> listeners;
    
    // lijnkleur
    private Color color;
    
    // gegenereerde naam van de speler
    private String name;
    
    // controls voor deze speler
    private ControlSet controls;
    
    // de lijn van deze speler
    Line line;
    
    // manager van powerups
    private PlayerPowerupManager powerups;
    
    // flasg om te bepalen of de speler nog leeft
    boolean alive;
    
    // player score
    private int score;
    
    public Player()
    {
        // init waarden
        changeName();
        changeColor();
        changeControls();
        
        line = new Line(this);
        powerups = new PlayerPowerupManager();
        alive = true;
        score = 0;
        
        listeners = new Vector();
        GameManager.addListener(this);
    }
    
    public void addListener(PlayerListener listener)
    {
        if (!listeners.contains(listener))
            listeners.add(listener);
    }
    
    public String changeName()
    {
        name = NameManager.generatePlayerName();
        return getName();
    }
    
    public String getName()
    {
        return name;
    }
    
    public Color changeColor()
    {
        color = ColorManager.getNewColorSuggestion(color); // init
        return getColor();
    }
    
    public Color getColor()
    {
        return color;
    }
    
    public ControlSet changeControls()
    {
        controls = InputManager.generateControls(controls);
        controls.setOwner(this);
        return getControls();
    }
    
    public ControlSet getControls()
    {
        return controls;
    }
    
    public Line getLine()
    {
        return line;
    }
    
    public boolean hasPowerup()
    {
        return powerups.hasAbilityPowerup();
    }
    
    // geef de ability powerup die de speler heeft
    public AbilityPowerup getPowerup()
    {
        if (!hasPowerup()) return null;
        return powerups.getAbilityPowerup();
    }
    
    public void deactivatePowerups()
    {
        powerups.deactivate();
    }
    
    public void usePowerup()
    {
        // we moeten nu nog wel bepalen of het zin heeft.
        // heeft de player wel een powerup?
        // is er al een powerup aan de gang? maakt dat uit?
        AbilityPowerup ap = powerups.getAbilityPowerup();
        ap.activate();
        
        // notify listeners
        GamePowerupManager.powerupActivated(ap);
    }
    
    // de powerup heeft aangegeven dat hij op is
    public void powerupUsed(AbilityPowerup power)
    {
        powerups.trashPowerup(power);
        
        // notify listeners
        GamePowerupManager.powerupDeactivated(power);
    }
    
    // we hebben een powerup!
    public synchronized void pickUpPowerup(Powerup p)
    {
        // zorg ervoor dat de powerups bij de player kunnen komen
        p.setOwner(this);
        
        // voeg toe aan powerup bibliotheek
        powerups.addPowerup(p);
        
        System.out.println(Util.getLogTimeString(GameManager.getGameTime()) + 
                "Player '" + name + "' picked up powerup: " + 
                p + " (" + p.getX() + "," + p.getY() + ")");
        
        // notify listeners
        GamePowerupManager.powerupPickedUp(p);
    }
    
    // sommige powerups zal je ingedrukt moeten houden
    public void pausePowerup()
    {
        
    }
    
    public boolean isAlive()
    {
        return alive;
    }

    // met een powerup kunnen we mogelijk iemand uit de dood halen
    public void setAlive(boolean alive)
    {
        this.alive = alive;
        
        // notify listeners
        if (!alive)
        {
            for (PlayerListener listener : listeners)
                listener.playerDied(this); // tegen de muur aangekomen
        }
    }
    
    public void killedBy(Player killer)
    {
        // doe niet setAlive, want dan kunnen de listeners mogelijk denken
        // dat de speler tegen de muur is aangekomen
        alive = false;
        
        for (PlayerListener listener : listeners)
        {
            listener.playerKilledPlayer(killer, this);
        }
    }
    
    public int getScore()
    {
        return score;
    }
    
    public void increaseScore()
    {
        score++;
    }

    //
    public void gameStarted()
    {
        
    }

    public void gameEnded()
    {
        score = 0;
    }

    public void roundStarted()
    {
        alive = true;
        line.startRound();
    }

    public void roundEnded()
    {
        deactivatePowerups();
    }
    
    public String toString()
    {
        return name;
    }
}
